import org.junit.Test;

import java.util.Arrays;
import java.util.List;

import static org.junit.Assert.*;

public class PaperListTest {

    private PaperList createPaperList() {
        return new PaperList("Rainy", Arrays.asList(
                new Thesis("Science"),
                new ConferencePaper("Science"),
                new JournalPaper("Technology")
        ));
    }

    // 测试用例1: 正常选择（类型匹配）
    @Test
    public void testNormalSelection() throws Exception {
        PaperList list = createPaperList();
        Student student = new Student("Cloudy", 1, PaperType.Thesis);
        List<Paper> result = list.selectPaper(student);
        assertEquals(1, result.size());
        assertTrue(result.get(0) instanceof Thesis);
    }

    // 测试用例2: 论文数量不足
    @Test(expected = NoEnoughPapersException.class)
    public void testNotEnoughPapers() throws Exception {
        PaperList list = createPaperList();
        Student student = new Student("Stormy", 4, PaperType.JournalPaper);
        list.selectPaper(student);
    }

    // 测试用例3: 学生重复选择
    @Test(expected = IllegalArgumentException.class)
    public void testDuplicateSelection() throws Exception {
        PaperList list = createPaperList();
        Student student = new Student("Cloudy", 1, PaperType.Thesis);
        list.selectPaper(student);
        list.selectPaper(student); // 第二次选择
    }

    // 测试用例4: 无效论文数量（0篇）
    @Test(expected = IllegalArgumentException.class)
    public void testInvalidQuantityZero() throws Exception {
        PaperList list = createPaperList();
        Student student = new Student("Snowy", 0, PaperType.Thesis);
        list.selectPaper(student);
    }

    // 测试用例5: 无效论文数量（5篇）
    @Test(expected = IllegalArgumentException.class)
    public void testInvalidQuantityFive() throws Exception {
        PaperList list = createPaperList();
        Student student = new Student("Haily", 5, PaperType.JournalPaper);
        list.selectPaper(student);
    }

    // 测试用例6: 类型为null
    @Test(expected = IllegalArgumentException.class)
    public void testNullPaperType() throws Exception {
        PaperList list = createPaperList();
        Student student = new Student("Thunder", 1, null);
        list.selectPaper(student);
    }

    // 测试用例7: 学生对象为null
    @Test(expected = IllegalArgumentException.class)
    public void testNullStudent() throws Exception {
        PaperList list = createPaperList();
        list.selectPaper(null);
    }

    // 测试用例8: Visitor模式验证
    @Test
    public void testVisitorPattern() throws Exception {
        PaperList list = createPaperList();
        list.selectPaper(new Student("Cloudy", 1, PaperType.Thesis));

        StudentCountVisitor visitor = new StudentCountVisitor();
        list.getSelectionResult().accept(visitor);
        assertEquals(1, visitor.getCount());
    }
    
}